local f = CreateFrame"Frame"
local dataobj
do
	local ldb = LibStub("LibDataBroker-1.1", true)
	dataobj = ldb and ldb:NewDataObject("JwDB", {
	type = "data source",
	value = 0,
	suffix = "msgs"
})
end

f:SetScript("OnEvent", function (self, event, ...)
	local handler = self[event]
	if handler then return handler(self, event, ...) end
end)

function f:CHAT_MSG_WHISPER(event, message, author)
	if oRA and oRA:HasModule("LeaderInvite") and message == oRA:GetModule("LeaderInvite").db.profile.keyword then return end
	WhisperDB[#WhisperDB + 1] = { date"%Y/%m/%d %H:%M:%S", author, message, event == "CHAT_MSG_WHISPER" }
	if dataobj then dataobj.value = #WhisperDB end
end

f.CHAT_MSG_WHISPER_INFORM = f.CHAT_MSG_WHISPER

local t = {}
local function GetTime(s)
	local year, month, day, hour, min, sec = s:match("(%d+)/(%d+)/(%d+) (%d+):(%d+):(%d+)")
	t.year = tonumber(year)
	t.month = tonumber(month)
	t.day = tonumber(day)
	t.hour = tonumber(hour)
	t.min = tonumber(min)
	t.sec = tonumber(sec)
	return time(t)
end

local AddMessage = getmetatable(DEFAULT_CHAT_FRAME).__index.AddMessage
local function print(s, ...)
	if s:find("%", nil, true) then
		s = s:format(...)
	end
	AddMessage(DEFAULT_CHAT_FRAME, "|cff20b090WhisperDB|r "..s)
end

local function printwhisper(s, p)
	p = p or print
	p("|cff808080[%s]|r%s |cffffff80%s|r |cff%s%s|r",s[1], s[4] and "From" or "To", s[2], s[4] and "ff8000" or "0080ff", s[3])
end

local sureclear
local function clearDB()
	local time = time()
	if sureclear and (time - sureclear) < 5 then
		WhisperDB = {}
		sureclear = nil
		print("Database cleared")
	else
		print("Confirm whisper database reset by reentering this command within 5 seconds")
		sureclear = time
	end
end

local function clearRecipient(name)
	local db, index, count = WhisperDB, 1, 0
	while true do
		local entry = db[index]
		if not entry then break end
		if entry[2] == name then
			count = count + 1
			table.remove(db, index)
		else
			index = index + 1
		end
	end
	print("Removed all %d whispers from %s", count, name)
end

local function clearBefore(time)
	local db = WhisperDB
	local count = #db
	local older = count
	while older >= 1 do
		local t = GetTime(db[older][1])
		if t < time then
			break
		else
			older = older - 1
		end
	end
	local remainder = count - older
	for i = 1, remainder do
		db[i] = db[older + i]
	end
	for i = count, remainder + 1, -1 do
		db[i] = nil
	end
	return older
end

SlashCmdList.JERRY_WHISPERS = function (input)
	local command, param = input:match("(%S+)%s*(.*)")

	if not command then
		print("Usage:")
		print("|cffffff80clear [<name>]|r : Clear the database (must enter the command twice)")
		print("|cffffff80clearold [<days>]|r : Remove whispers older than <days> days (default to 30)")
		print("|cffffff80last [<count>]|r : Show last <count> whispers (default to 5)")
		print("|cffffff80<name> [<count>]|r : Show last <count> whispers from <name> (default to 5)")
	elseif command == "info" then
		print("Database contains %d whispers", #WhisperDB)
	elseif command == "clear" then
		if param then
			clearRecipient(param)
		else
			clearDB()
		end
	elseif command == "clearold" then
		local days = tonumber(param) or 30
		local time = time() - (days * 60*60*24)
		local cleared = clearBefore(time)
		print("Removed %d whispers that were older than %d days", cleared, days)
	elseif command == "last" then
		local total = #WhisperDB
		local count = math.min(total, tonumber(param) or 5)
		for i = total - count + 1, total do
			printwhisper(WhisperDB[i])
		end
	else
		local last = {}
		local count = tonumber(param) or 5
		local db = WhisperDB
		for i = #db, 1, -1 do
			local w = db[i]
			if w[2] == command then
				last[#last + 1] = w
				if #last > count then break end
			end
		end
		if #last >= 1 then
			for i = #last, 1, -1 do
				printwhisper(last[i])
			end
		else
			print("No whisper found from %s", command)
		end
	end
end
SLASH_JERRY_WHISPERS1="/jwdb"

f:RegisterEvent"CHAT_MSG_WHISPER"
f:RegisterEvent"CHAT_MSG_WHISPER_INFORM"
f:RegisterEvent"PLAYER_LOGIN"

function f:PLAYER_LOGIN()
	WhisperDB = WhisperDB or {}
	if dataobj then dataobj.value = #WhisperDB end
	print("Database loaded (%d whispers). use /jwdb to access", #WhisperDB)
	self:UnregisterEvent"PLAYER_LOGIN"
	self.PLAYER_LOGIN = nil
end

if dataobj then
	local function printtt(s, ...)
		if s:find("%", nil, true) then
			s = s:format(...)
		end
		GameTooltip:AddLine(s)
	end

	function dataobj.OnTooltipShow(tooltip)
		tooltip:ClearLines()
		tooltip:AddLine('Whisper Database')
		local total = #WhisperDB
		local count = math.min(total, 3)
		for i = total - count + 1, total do
			printwhisper(WhisperDB[i], printtt)
		end
		tooltip:Show()
	end
end
